﻿package at.geoathome.utils.lang
{
	import flash.errors.IOError;
	import flash.text.TextField;
	
	import flash.display.Loader;
	import flash.events.EventDispatcher;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLLoaderDataFormat;
	
	/**
	* ...
	* @author Georg Kamptner
	*/
	public class Language extends EventDispatcher
	{
		private var _language_code:String;
		private var _xml_path:String;
		private var _loader:URLLoader;
		private var _strings:Object;
		private var _loaded:Boolean;
		private var _load_callback:Function;
		private var _language_receivers:Array;
		private var _language_receivers_string_id:Array;
		
		public function Language(language_code:String, xml_path:String) 
		{
			_strings = new Object();
			_loader = new URLLoader();
			_loaded = false;
			_language_receivers = new Array();
			_language_receivers_string_id = new Array();
			_language_code = language_code;
			_xml_path = xml_path;
			
			// init _loader
			_loader.dataFormat = URLLoaderDataFormat.TEXT;
			_loader.addEventListener(Event.COMPLETE, onLoaded);
			_loader.addEventListener(IOErrorEvent.IO_ERROR, onLoadedIOError);
		}
		
		public function set xml_path(xml_path:String):void {
			_xml_path = xml_path;
		}
		
		public function get loaded():Boolean {
			return _loaded;
		}
		
		public function set load_callback(load_callback:Function):void {
			_load_callback = load_callback;
		}
		
		
		public function loadLanguageXML(xml_path:String = null, force_reload:Boolean = false, custom_xml_complete_callback:Function = null):void
		{
			// break condition
			if (_loaded && !force_reload)
				return;
				
			_loaded = false;
			
			if(xml_path != null)
				_xml_path = xml_path;
			
			if (custom_xml_complete_callback != null)
				_load_callback = custom_xml_complete_callback;
			
			if(_xml_path != null)
				_loader.load(new URLRequest(_xml_path));
		}
		
		public function onLoadedIOError(e:IOErrorEvent):void
		{
			// call load callback function
			if(_load_callback != null)
				_load_callback(e);
			
			throw new IOError("Language load failed.");
		}
		
		public function onLoaded(e:Event = null):void
		{	
			// get XML
			var data:XML = new XML(e.target.data);
			data.ignoreWhitespace = true;
			for each (var entry:XML in data.entry)
			{
				_strings[entry.@ref] = entry;
			}
			
			_loaded = true;
			
			// call load callback function
			if(_load_callback != null)
				_load_callback(e);
			
			handleLanguageReceivers();
		}
		
		public function getString(string_id:String):String
		{
			if (!stringIdExists(string_id))
				return string_id;
				
			return _strings[string_id];
		}
		
		public function setString(string_id:String, string_value:String):String {
			return _strings[string_id] = string_value;
		}
		
		public function stringIdExists(string_id:String):Boolean
		{
			if (_strings[string_id] != undefined && _strings[string_id] != null)
				return true;
			return false;
		}
		
		public function addReceiver(object:Object, string_id:String):void
		{
			_language_receivers.push(object);
			_language_receivers_string_id.push(string_id);
			
			if (_loaded)
				handleLanguageReceivers();
		}
		
		public function removeReceiver(object:Object, string_id:String):void
		{
			var i:uint = 0;
			var l:uint = _language_receivers.length;
			for (; i < l; ++i)
			{
				if (_language_receivers[i] == null) // skip null entries
					continue;
				
				if (_language_receivers[i] == object && _language_receivers_string_id[i] == string_id)
				{
					_language_receivers[i] = null;
					_language_receivers_string_id[i] = null;
				}
			}			
		}
		
		// Updates the text property of all registered receivers
		private function handleLanguageReceivers():void
		{
			var i:uint = 0;
			var l:uint = _language_receivers.length;
			for (; i < l; ++i)
			{
				if (_language_receivers[i] == null) // skip null entries
					continue;
				

				if (_language_receivers[i] is IMultiLanguageReceiver){
					(_language_receivers[i] as IMultiLanguageReceiver).text = getString(_language_receivers_string_id[i]);
				}
				else
				{
					try {
						_language_receivers[i].text = getString(_language_receivers_string_id[i]);
					} catch (e:Error) {
						throw new Error("Receivers have to implement the IMultiLanguageReceiver Interface or a 'set text(value:String):void' - Method. \n original Error(" + e.errorID + "):" + e.message + "\n");
					}
				}
			}
		}
		
		public override function toString():String
		{
			var str:String = "";
			str += "\n [com.kronomy.utils.lang.Language] \n ";
			for (var i:String in _strings)
			{
				str += i + ": " + _strings[i] + " \n";
			}
			
			return str;
		}
	}
	
}